/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.delivery.web;

import com.mycompany.delivery.dto.ContactDTO;
import com.mycompany.delivery.dto.UserDTO;
import com.mycompany.delivery.servicelayer.ContactService;
import com.mycompany.delivery.servicelayer.UserService;
import com.mycompany.delivery.validation.CourierSpringValidator;
import com.mycompany.delivery.validation.EmployeeSpringValidator;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;

/**
 *
 * @author Katarína Hrabovská <katarina.hrabovska1992@gmail.com>
 */
@Controller
@RequestMapping("/employee")
public class EmployeeController {

    final static Logger log = LoggerFactory.getLogger(EmployeeController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private ContactService contactServices;

    @Autowired
    private MessageSource messageSource;

    @ModelAttribute("contacts")
    public List<ContactDTO> allContact() {
        log.debug("allContacts()");
        return contactServices.getAllContacts();
    }

    @ModelAttribute("employees")
    public List<UserDTO> allEmployees() {
        log.debug("allEmployees()");
        return userService.getAllEmployees();
    }

    @RequestMapping(value = "/formR", method = RequestMethod.GET)
    public String rece(Model model) {
        log.debug("rece()");
        model.addAttribute("employee", new UserDTO());
        return "employee/formR";
    }

    @RequestMapping(value = "/find", method = RequestMethod.GET)
    public String findDef(Model model) {
        model.addAttribute("string", new String());

        model.addAttribute("contacts", new ArrayList<ContactDTO>());
        log.debug("find(model={})", model);
        return "employee/formR";
    }

    @RequestMapping(value = "/find/{name}", method = RequestMethod.GET)
    public String findDef(@PathVariable String name, Model model) {
        model.addAttribute("string", new String());

        model.addAttribute("contacts", contactServices.findContactBySurname(name));
        log.debug("find(model={})", model);
        return "employee/formR";
    }

    @RequestMapping(value = "/new/{id}", method = RequestMethod.POST)
    public String newContact(@PathVariable Long id, Model model, UriComponentsBuilder builder) {
        return "redirect:" + builder.path("/employee/new/" + id).build();
    }

    @RequestMapping(value = "/new/{id}", method = RequestMethod.GET)
    public String newContact2(@PathVariable Long id, Model model) {
        ContactDTO c = contactServices.find(id);
        log.debug("listNova()");
        model.addAttribute("contact", id);
        UserDTO u = new UserDTO();
        u.setContact(c);
        model.addAttribute("employee", u);
        return "employee/new";
    }

    @RequestMapping(value = "/find", method = RequestMethod.POST)
    public String finded(@RequestParam("name") String name, Model model, UriComponentsBuilder builder, Locale locale) {
        String n = name;
        log.debug("atribut1 {} loc {}", name, locale);
        try {
            n = UriUtils.encodePath(name, "UTF-8");
        } catch (Exception ex) {
        }
        log.debug("atribut2 {}", n);
        log.debug("find(model={})", model);

        return "redirect:" + builder.path("/employee/find/" + n).build();
    }

    @RequestMapping(value = "/new", method = RequestMethod.GET)
    public String listNovy(Model model) {
        log.debug("listNovy()");
        model.addAttribute("employee", new UserDTO());
        return "employee/new";
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public String delete(@PathVariable long id, RedirectAttributes redirectAttributes, Locale locale, UriComponentsBuilder uriBuilder) {
        log.debug("delete({})", id);
        UserDTO employee = userService.findEmployee(id);
        userService.removeEmployee(employee);
        redirectAttributes.addFlashAttribute(
                "message",
                messageSource.getMessage("employee.delete.message", new Object[]{employee.getId()}, locale)
        );
        return "redirect:" + uriBuilder.path("/employee/list").build();
    }

    @RequestMapping(value = "/update/{id}", method = RequestMethod.GET)
    public String update_form(@PathVariable long id, Model model) {
        UserDTO user = userService.findEmployee(id);
        model.addAttribute("employee", user);
        log.debug("update_form(model={})", model);
        return "employee/edit";
    }

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(Model model) {
        log.debug("list()");
        model.addAttribute("employee", new UserDTO());
        return "employee/list";
    }

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(new EmployeeSpringValidator());
    }

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String update(@Valid @ModelAttribute UserDTO employee, BindingResult bindingResult, Model model, RedirectAttributes redirectAttributes, Locale locale, UriComponentsBuilder uriBuilder) {
        log.debug("update(locale={}, employee={})", locale, employee);
        EmployeeSpringValidator validator = new EmployeeSpringValidator();
        validator.validate(employee, bindingResult);
        
        if (bindingResult.hasErrors()) {
            log.debug("binding errors");
            for (ObjectError ge : bindingResult.getGlobalErrors()) {
                log.debug("ObjectError: {}", ge);
            }
            for (FieldError fe : bindingResult.getFieldErrors()) {
                log.debug("FieldError: {}", fe);
                
           model.addAttribute("employee", employee);
           String mailmessage = messageSource.getMessage(fe,  locale);
           model.addAttribute("message", mailmessage);
            }
            return employee.getId() == null ? "employee/list" : "employee/edit";
        }
        
        
            /*if (employee.getLogin() == null || "".equals(employee.getLogin()) ) {
                redirectAttributes.addFlashAttribute(
                        "message",
                        messageSource.getMessage("user.nologin", new Object[]{employee}, locale)
                );
                return employee.getId() == null ? "employee/list" : "employee/edit";
            }
            
            if (employee.getContact() == null) {
                redirectAttributes.addFlashAttribute(
                        "message",
                        messageSource.getMessage("user.noContact", new Object[]{employee}, locale)
                );
                return employee.getId() == null ? "employee/list" : "employee/edit";
            }
            
           if (!(employee.getLogin().matches("^[a-zA-Z0-9_-]{5,20}$"))) {
                redirectAttributes.addFlashAttribute(
                        "message",
                        messageSource.getMessage("courier.wrongLogin", new Object[]{employee.getLogin()}, locale)
                );
                return employee.getId() == null ? "employee/list" : "employee/edit";
            }*/
           
        employee.setContact(contactServices.find(employee.getContact().getId()));
        
        if (employee.getId() == null) {
            if (userService.findUserByLogin(employee.getLogin()) != null) {
                redirectAttributes.addFlashAttribute(
                        "message",
                        messageSource.getMessage("courier.login.notUnique", new Object[]{employee.getLogin()}, locale)
                );
                return "redirect:" + uriBuilder.path("/employee/list").build();
            }
            userService.createEmployee(employee);
            redirectAttributes.addFlashAttribute(
                    "message",
                    messageSource.getMessage("employee.add.message", new Object[]{employee.getId()}, locale)
            );
        } else {
            userService.updateEmployee(employee);
            redirectAttributes.addFlashAttribute(
                    "message",
                    messageSource.getMessage("employee.updated.message", new Object[]{employee.getId()}, locale)
            );
        }
        return "redirect:" + uriBuilder.path("/employee/list").build();
    }
}
